package com.sk.weichat.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.RelativeLayout;

import com.jakewharton.rxbinding2.widget.RxTextView;
import com.sk.weichat.R;

import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;


/**
 * 圆角矩形输入框 //不支持paddding wrap_content
 * lzs
 */
public class RoundRectInputEditText extends RelativeLayout implements TextWatcher {
    private int textSize;
    private int textColor;

    private boolean textStyle; //true :加粗 false: 正常

    private int rectBackground;
    private int rectWidth;
    private int rectHeight;
    private int rectMargin;

    private int textNum;
    //圆角半径
    private int radius;
    //圆角描边大小
    private int strokeWidth;
    //圆角描边颜色
    private int strokeColor;

    private int corsorColor;
    private boolean corsorVisiable = false;

    private int cursorHeight;
    private int cursorWidth;

    private String hint = "";

    private int hintSize;

    private int hintColor;

    //底部破折号宽度
    private int dashWidth;
    //破折号间隙
    private int dashGap;

    private int dashColor;
    //
    private int dashSelectedColor = 0xfffd8420;

    private int selectIndex = -1;

    private int h;

    private int w;

    private final static int dashSize = 1; //1px

    private Paint mPaint;

    private char[] charArray = null;
    //private List<String> mStrList = new ArrayList<>();

    private int textChangeWacthTime = 1;


    private AppCompatEditText editText;

    private boolean flag = true;

    public RoundRectInputEditText(Context context) {
        this(context, null);
    }

    public RoundRectInputEditText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundRectInputEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundRectInputEdittext, defStyleAttr, 0);

        textNum = a.getInteger(R.styleable.RoundRectInputEdittext_textNum, 4);
        radius = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_radius, 0);
        strokeWidth = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_strokeWidth, 0);
        strokeColor = a.getColor(R.styleable.RoundRectInputEdittext_strokeColor, 0);
        rectBackground = a.getColor(R.styleable.RoundRectInputEdittext_rectBackground, 0xFFFFFF);
        rectWidth = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_rectWidth, 0);
        rectHeight = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_rectHeight, 0);
        rectMargin = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_rectMargin, 0);

        corsorColor = a.getColor(R.styleable.RoundRectInputEdittext_corsorColor, 0x000000);

        textSize = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_tSize, dp2px(context, 17));
        textStyle = a.getInteger(R.styleable.RoundRectInputEdittext_tStyle, 0) == 0 ? false : true;

        hintSize = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_hintSize, dp2px(context, 17));

        dashWidth = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_dashWidth, dp2px(context, 40));

        dashGap = a.getDimensionPixelSize(R.styleable.RoundRectInputEdittext_dashGap, dp2px(context, 10));

        hintColor = a.getColor(R.styleable.RoundRectInputEdittext_hintColor, 0xFFCCCCCC);

        dashColor = a.getColor(R.styleable.RoundRectInputEdittext_dashColor, 0xFFCCCCCC);

        dashSelectedColor = a.getColor(R.styleable.RoundRectInputEdittext_dashSelectedColor, 0xfffd8420);

        hint = a.getString(R.styleable.RoundRectInputEdittext_hint);

        textColor = a.getColor(R.styleable.RoundRectInputEdittext_tColor, 0xFF666666);

        a.recycle();

        editText = new AppCompatEditText(context);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            editText.setBackground(null);
        } else {
            editText.setBackgroundColor(Color.WHITE);
        }
        editText.setTextColor(0x00ffffff);
        editText.setTextSize(0.1f);
        editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(textNum)});
        editText.setInputType(EditorInfo.TYPE_NUMBER_FLAG_SIGNED | EditorInfo.TYPE_CLASS_NUMBER);
        editText.setFocusable(true);

        editText.addTextChangedListener(this);

        editText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    selectIndex = -1;
                    corsorVisiable = false;
                } else {
                    selectIndex = editText.getSelectionStart();
                    corsorVisiable = true;

                }
                invalidate();
            }
        });
        //缓存
        rectfCache = new RectF[textNum];

        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        layoutParams.width = textNum * rectWidth + (textNum - 1) * rectMargin;

        addView(editText, layoutParams);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);


        cursorHeight = dp2px(context, 20);

        cursorWidth = dp2px(context, 2);

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (flag) {
                    corsorVisiable = !corsorVisiable;
                    postInvalidate();
                    try {
                        Thread.sleep(700);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        editText.requestFocus();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        // 画圆角矩形
        drawRoundRect(canvas, mPaint);
        //画文字
        drawTextOrHint(canvas, mPaint);
        //画光标
        drawCursor(canvas, mPaint);
    }

    private RectF[] rectfCache;

    private void drawRoundRect(Canvas canvas, Paint mPaint) {
//        Log.e("lzs", "width:" + w + "height:" + h);
//        Log.e("lzs", "rectWidth:" + rectWidth + "  rectMargin:" + rectMargin + "  strokeWidth:" + strokeWidth + "  rectHeight:" + rectHeight);

        //居中
        float margin = (w - (textNum * rectWidth + (textNum - 1) * rectMargin)) / 2;

        for (int i = 0; i < textNum; i++) {
            //先画背景
            mPaint.setColor(rectBackground);
            mPaint.setStyle(Paint.Style.FILL);

            float left = i * 1.0f * (rectWidth + rectMargin) + strokeWidth + margin;
            float top = (h - rectHeight) * 1.0f / 2 + strokeWidth;
            float right = (i + 1) * rectWidth + i * rectMargin - strokeWidth + margin;
            float bottom = (h + rectHeight) * 1.0f / 2 - strokeWidth;
            RectF rect = new RectF(left, top, right, bottom);
            rectfCache[i] = rect;
            canvas.drawRoundRect(rect, radius - strokeWidth, radius - strokeWidth, mPaint);
            // Log.e("lzs", "rect:" + rect);

            //描边
            mPaint.setColor(strokeColor);
            mPaint.setStrokeWidth(strokeWidth);
            mPaint.setStyle(Paint.Style.STROKE);
            RectF rectF2 = new RectF(left - strokeWidth, top - strokeWidth, right + strokeWidth, bottom + strokeWidth);
            canvas.drawRoundRect(rectF2, radius, radius, mPaint);
            //Log.e("lzs", "rectF2:" + rectF2);

            //
        }
    }

    private void drawCursor(Canvas canvas, Paint mPaint) {
        if (selectIndex >= 0 && selectIndex < textNum && corsorVisiable) {
            mPaint.setColor(corsorColor);
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            mPaint.setStrokeWidth(cursorWidth);
            RectF rectF = rectfCache[selectIndex];
            float startX = rectF.left + rectF.width() / 2;
            float startY = rectF.top + (rectF.height() - cursorHeight) / 2;
            float stopX = rectF.left + rectF.width() / 2;
            float stopY = rectF.bottom - (rectF.height() - cursorHeight) / 2;
            canvas.drawLine(startX, startY, stopX, stopY, mPaint);
        }
    }


    private void drawTextOrHint(Canvas canvas, Paint mPaint) {
        mPaint.setColor(textColor);
        mPaint.setTextSize(textSize);
        mPaint.setTextAlign(Paint.Align.CENTER);

        if (charArray == null || charArray.length == 0) {
            //画hint
//                mPaint.setColor(hintColor);
//                mPaint.setTextSize(hintSize);
//                mPaint.setTextAlign(Paint.Align.CENTER);
//                Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
//                float textWidth = mPaint.measureText(hint);
//                //写提示语
//                Rect targetRect = new Rect(0, 0, (int) textWidth, h);
//                int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
//                //Log.d("lzs", "baseline:" + baseline + "   textWidth:" + textWidth);
//                canvas.drawText(hint, textWidth / 2, baseline, mPaint);
        } else {
            mPaint.setColor(textColor);
            mPaint.setTextSize(textSize);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setTextAlign(Paint.Align.CENTER);
            if (textStyle) {
                mPaint.setTypeface(Typeface.DEFAULT_BOLD);
            } else {
                mPaint.setTypeface(Typeface.DEFAULT);
            }
            for (int i = 0; i < charArray.length; i++) {

                String text = new String(new char[]{charArray[i]});
                Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
                //测量文字宽度
                float textWidth = mPaint.measureText(text);

                RectF cache = rectfCache[i];
                float left = cache.left + cache.width() / 2;

                float right = left + textWidth;
                RectF textRect = new RectF(left, cache.top, right, cache.bottom);
                //相对于baseline 的Y轴位置
                int baselineY = (int) ((textRect.bottom + textRect.top - fontMetrics.bottom - fontMetrics.top) / 2);

                canvas.drawText(text, left, baselineY, mPaint);

            }
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.h = h;
        this.w = w;
    }


    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (mTextWatcher != null && mTextWatcher.get() != null) {
//            mTextWatcher.get().afterTextChanged(s);
//        }
            String string = s.toString();
            if (!TextUtils.isEmpty(string)) {
                charArray = string.toCharArray();
                if (charArray.length < textNum) {
                    editText.setSelection(charArray.length);
                }
                selectIndex = charArray.length;
            } else {
                charArray = null;
                editText.setSelection(0);
                selectIndex = 0;
            }
            //
            invalidate();
        }
    }

    public void setTextWatcher(Observer<CharSequence> mTextWatcher) {
        this.mTextWatcher = new WeakReference<Observer<CharSequence>>(mTextWatcher);
        if (mTextWatcher != null) {
            RxTextView.textChanges(editText)
                    .throttleLast(textChangeWacthTime, TimeUnit.SECONDS)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(mTextWatcher);
        }


    }

    private WeakReference<Observer<CharSequence>> mTextWatcher;


    private int px2dp(Context context, int px) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (px / scale + 0.5f);
    }

    private int dp2px(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }


    public void setText(CharSequence charSequence){
        editText.setText(charSequence);
    }
    /**
     * 反射设置光标颜色
     */
//    public static void setCursorDrawableColor(EditText editText, int color) {
//        try {
//            Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");//获取这个字段
//            fCursorDrawableRes.setAccessible(true);//代表这个字段、方法等等可以被访问
//            int mCursorDrawableRes = fCursorDrawableRes.getInt(editText);
//
//            Field fEditor = TextView.class.getDeclaredField("mEditor");
//            fEditor.setAccessible(true);
//            Object editor = fEditor.get(editText);
//
//            Class<?> clazz = editor.getClass();
//            Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable");
//            fCursorDrawable.setAccessible(true);
//
//            Drawable[] drawables = new Drawable[2];
//            drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
//            drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes);
//            drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN);//SRC_IN 上下层都显示。下层居上显示。
//            drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN);
//            fCursorDrawable.set(editor, drawables);
//        } catch (Throwable ignored) {
//
//        }
//    }
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        flag = false;
    }
}
